package com.mr;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.mr.utils.EsUtils;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.search.*;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.Test;

import java.io.IOException;

public class testId {
    private ObjectMapper objectMapper = new ObjectMapper();
    private RestHighLevelClient client = EsUtils.getClient();
    private String index = "person";

    @Test
    private void testId() throws Exception {
        GetRequest getRequest = new GetRequest(index, "1");
        //getgetgetget
        GetResponse documentFields = client.get(getRequest, RequestOptions.DEFAULT);
        System.out.println(documentFields.getSourceAsMap());
    }

    @Test
    private void testids() throws Exception {
        SearchRequest searchRequest = new SearchRequest(index);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.idsQuery("1", "2", "3"));
        searchRequest.source(searchSourceBuilder);
        SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
        for (SearchHit hit : search.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }

    }

    @Test
    private void testPrefix() throws IOException {
        //前缀查询
       /* POST book/_search
        {
            "query": {
            "prefix": {
                "name": {
                    "value": "金"
                }
            }
        }
        }*/
        SearchRequest searchRequest = new SearchRequest(index);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.prefixQuery("desc", "修仙"));
        searchRequest.source(searchSourceBuilder);
        SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
        for (SearchHit hit : search.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }


    }

    @Test
    private void testmhu() throws Exception {
           /* POST book/_search
        {
            "query": {
            "fuzzy": {
                "desc": {
                    "value": "讲述潘",
                            "prefix_length": 2     # 指定前面几个字符是不允许出现错误的
                }
            }
        }
        }*/
        SearchRequest searchRequest = new SearchRequest(index);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.fuzzyQuery("desc", "讲述潘").prefixLength(2));
        searchRequest.source(builder);
        SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
        for (SearchHit hit : search.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }


    }

    //通配查询，和，mysql中的like相似占位符
    @Test
    private void testwildcard() throws IOException {
/*# wildcard 查询
POST book/_search
{
  "query": {
    "wildcard": {
      "desc": {
        "value": "李*"      # 可以使用*和？指定通配符和占位符
      }
    }
  }
} */
        SearchRequest searchRequest = new SearchRequest(index);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.wildcardQuery("desc", "李*"));
        searchRequest.source(builder);


        SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
        for (SearchHit hit : search.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }
    }

    //范围查询
    @Test
    private void testRange() throws Exception {
           /* POST book/_search
            {
                "query": {
                "range": {
                    "count": {
                        "gte": 1000000,
                                "lte": 2000000
                    }
                }
            }
            }*/
        SearchRequest searchRequest = new SearchRequest(index);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.rangeQuery("count").lte(2000000).gte(1000000));
        searchRequest.source(builder);

        SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
        for (SearchHit hit : search.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }
    }

    @Test
    private void _search() throws Exception {
        SearchRequest searchRequest = new SearchRequest(index);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.regexpQuery("name","[a-z]{4}"));
        searchRequest.source(builder);

        SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
        for (SearchHit hit : search.getHits().getHits()) {

            System.out.println(hit.getSourceAsMap());
        }

    }
  //深分页
 /* POST book/_search?scroll=1m
    {
        "query": {
        "match_all": {}
    },
        "size": 2,
            "sort": [
        {
            "count": {
            "order": "desc"
        }
        }
  ]
    }*/
 @Test
    private void Testfy()throws Exception{
     SearchRequest searchRequest = new SearchRequest(index);
     //指定scroll信息, scrollId的生存时间一分钟
     searchRequest.scroll(TimeValue.timeValueMillis(1l));
     SearchSourceBuilder builder = new SearchSourceBuilder();
     builder.from(0);
     builder.size(2);
     //jiangxu
     builder.sort("count", SortOrder.DESC);
     builder.query(QueryBuilders.matchAllQuery());
     searchRequest.source(builder);

     SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
     String scrollId = search.getScrollId();
     //翻页
     /*POST /book/_search/scroll
     {
         "scroll_id": "<根据第一步得到的scorll_id去指定>",
             "scroll": "<scorll信息的生存时间>"
     }*/
     while (true){
         SearchScrollRequest searchScrollRequest = new SearchScrollRequest(scrollId);
         //分页的时候翻页
        //里面放上时间和翻页的id
         searchScrollRequest.scroll(TimeValue.timeValueMillis(1l));
         SearchResponse scroll = client.scroll(searchScrollRequest, RequestOptions.DEFAULT);
         SearchHits hits = scroll.getHits();
         //panduan
         if(hits.getHits()!=null&&hits.getHits().length>0){
             for (SearchHit hit : search.getHits().getHits()) {

                 System.out.println(hit.getSourceAsString() );
             }
         }else {
             System.out.println("-------");
             break;
         }
         //释放es服务器身份也对应的上下文的内存空间
         ClearScrollRequest clearScrollRequest = new ClearScrollRequest();
         //qingli id
         clearScrollRequest.addScrollId(scroll.getScrollId());
         ClearScrollResponse clearScrollRequest1 = client.clearScroll(clearScrollRequest,RequestOptions.DEFAULT);
         System.out.println("删除scroll：" + clearScrollRequest1.isSucceeded());

     }
 }
 /*- must： 所有的条件，用must组合在一起，表示And的意思
- must_not：将must_not中的条件，全部都不能匹配，标识Not的意思
- should：所有的条件，用should组合在一起，表示Or的意思*/
 /*POST book/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "name": "java"
          }
        },{
          "match": {
            "desc": "李瓶"
          }
        }
      ]
    }
  }
}*/
    @Test
    private void testzhbool()throws Exception{
        SearchRequest searchRequest = new SearchRequest(index);
        //指定scroll信息, scrollId的生存时间一分钟

        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.from(0);
        builder.size(2);
        //创建多条件查询对象
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        boolQueryBuilder.should().add(QueryBuilders.matchQuery("name","java"));
        boolQueryBuilder.should().add(QueryBuilders.matchQuery("desc","李瓶"));
        //将多条查询对象放到查询对象中
        builder.query(boolQueryBuilder);

        //jiangxu
        builder.sort("count", SortOrder.DESC);
        builder.query(QueryBuilders.matchAllQuery());
        searchRequest.source(builder);

        SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
        String scrollId = search.getScrollId();
    }
    @Test
    private void testBoostingQuery()throws  Exception{
        //SearchRequest searchRequest, RequestOptions
        SearchRequest searchRequest = new SearchRequest(index);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.boostingQuery(
                QueryBuilders.matchQuery("desc","讲述"),
                QueryBuilders.matchQuery("desc","李瓶")
        ).negativeBoost(0.2f));
        SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);

    }
    //filter查询
    @Test
    private void testfilterQuery()throws  Exception{
        //SearchRequest searchRequest, RequestOptions
        SearchRequest searchRequest = new SearchRequest(index);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        boolQueryBuilder.must().add(QueryBuilders.matchQuery("desc","李瓶"));
        boolQueryBuilder.filter(QueryBuilders.rangeQuery("count").lte(4000000).gte(1));
        boolQueryBuilder.filter(QueryBuilders.termQuery("auth","古人"));

        builder.query(boolQueryBuilder);
        searchRequest.source(builder);
        SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
        //4. 输出结果
        for (SearchHit hit : search.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }
    }
    //高亮查询
    /*高亮查询就是将用户输入的关键字，以一定特殊形式展现，让用户知道为什么这个结果被检索出来
    * 高亮展示的数据，本身就是文档中的一个field，单独的激昂field以highlight的形式展现、
    * - fragment_size：指定高亮数据展示多少个字符回来。
- pre_tags：指定前缀标签，举个栗子< font color="red" >
- post_tags：指定后缀标签，举个栗子< /font >
- fields：指定哪几个Field以高亮形式返回*/
    @Test
    private void testHighLighQuery()throws  Exception{
        //SearchRequest searchRequest, RequestOptions
        SearchRequest searchRequest = new SearchRequest(index);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.matchQuery("desc","java讲述"));
        //高亮制定
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("desc",1)
                .preTags("<font color='red'>")
                .postTags("</font>");
        builder.highlighter(highlightBuilder);
        searchRequest.source(builder);
        SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
        //4. 输出结果
        for (SearchHit hit : search.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }


    }
    //聚合查询
    //Es的聚合查询和mysql的聚合查询类似，es的聚聚合查询bimysql的更添加强大
    @Test
    private void TestCardinality()throws  Exception{
        //SearchRequest searchRequest, RequestOptions
        SearchRequest searchRequest = new SearchRequest(index);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.aggregation(AggregationBuilders.cardinality("agg").field("count"));
        searchRequest.source(builder);
        SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
        Aggregation agg = search.getAggregations().get("agg");



    }


    @Test
    private void testExtendedStats()throws  Exception{
        //SearchRequest searchRequest, RequestOptions
        SearchRequest searchRequest = new SearchRequest(index);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.aggregation(AggregationBuilders.extendedStats("agg").field("count"));
        searchRequest.source(builder);
        SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
        Aggregation agg = search.getAggregations().get("agg");



    }

    @Test
    public void testDeleteByQuery() throws IOException {


        DeleteByQueryRequest  request = new DeleteByQueryRequest(index);
        request.setQuery(QueryBuilders.matchAllQuery());

       client.deleteByQuery(request, RequestOptions.DEFAULT);



    }
}
